import SintaksnoStablo
import sys
import pickle
class Jedinka:

    def __init__(self, naziv, red, jedinka):

        self.naziv = naziv
        self.redak = red
        self.sto_to_je = jedinka

class Analizator:
    def __init__(self,pocetni):
        self.lexJedinke = []
        self.stog = []
        self.sinkronizacijski_znakovi=[]
        self.stog.append(pocetni)
        self.redak_u_kodu = 0
        self.vrh_stoga = ""
        self.stablo = SintaksnoStablo.SintaksnoStablo()
        self.tablica = {}
        self.zavrsni_znakovi = []

    def procitaj_ulaz(self):

        sys.stdin = open("../probni/minusLang.in", "r")
        for line in sys.stdin:
            if len(line) == 0:
                break
            i1 = line.find(" ") +1
            i2 = line[i1:].find(" ")

            lex1 = line[:i1-1]
            lex2 = line[i1:][:i2]
            lex3 = line[i1:][i2+1:]
            jed = Jedinka(lex1, lex2, lex3.strip())
            self.lexJedinke.append(jed)

        jed = Jedinka("#", "", "")      #dodaje oznaku kraja niza
        self.lexJedinke.append(jed)


    def analiziraj(self, tablica):
        self.tablica = tablica

        i=0
        while ( len ( self.stog) > 0):

            self.vrh_stoga = self.stog.pop()                            #cita stanje na vrhu stoga
            self.stog.append(self.vrh_stoga)
            dodano = 0


            if ( self.vrh_stoga + "%" + self.lexJedinke[i].naziv not in tablica.keys() ): #oporavak od pogre
                izraz = "Greska u redu" + " " + self.lexJedinke[i].redak + "\n"
                #print(izraz)
                sys.stderr.write(izraz)
                izraz="procitani znak" + " " +self.lexJedinke[i].naziv+" "+self.lexJedinke[i].sto_to_je + "\n"
                #print(izraz)
                sys.stderr.write(izraz)
                for k in self.tablica.keys():
                    temp=k.split("%")
                    if temp[0] == self.vrh_stoga and temp[1] in self.zavrsni_znakovi:
                        izraz="ocekivani znak"+ " " +temp[1] + "\n"
                        #print(izraz)
                        sys.stderr.write(izraz)

                if self.lexJedinke[i].naziv != "#":
                    #i += 1
                    while self.lexJedinke[i].naziv not in self.sinkronizacijski_znakovi:
                        i += 1

                while self.vrh_stoga + "%" + self.lexJedinke[i].naziv not in self.tablica.keys()  and len(self.stog) >= 1:
                    self.stog.pop()

                    self.stog.pop()
                    self.vrh_stoga = self.stog.pop()                         #cita stanje na vrhu stoga
                    self.stablo.cvorovi.pop() #proba
                    self.stog.append(self.vrh_stoga)



            else:
                self.akcija = self.tablica [self.vrh_stoga + "%" + self.lexJedinke[i].naziv]
                #self.stablo.ispisi()
                #print()


                if (self.akcija.ime_akcije == "Pomakni"):

                    self.stog.append(self.lexJedinke[i].naziv)
                    self.stog.append(self.akcija.stanje)

                    self.stablo.dodaj_list(self.lexJedinke[i].naziv,
                                           self.lexJedinke[i].redak,
                                           self.lexJedinke[i].sto_to_je)
                    i += 1


                elif (self.akcija.ime_akcije == "Reduciraj"):

                    if (self.akcija.produkcija[1][0] != "$"):

                        for j in range (0, len(self.akcija.produkcija[1]) ):      #mice desnu stranu produkcije zajedno sa stanjima sa stoga
                            self.stog.pop()
                            self.stog.pop()

                        self.stablo.dodaj_cvor(self.akcija.produkcija[0],
                                               list(self.akcija.produkcija[1]))
                        dodano = 1

                    if not dodano:
                        self.stablo.dodaj_epsilon(self.akcija.produkcija[0])

                    tmp=self.stog.pop()
                    self.stog.append(tmp)
                    self.stog.append(self.akcija.produkcija[0])

                    kljuc = tmp + "%" + self.akcija.produkcija[0]
                    if (kljuc in self.tablica.keys()):
                        novo_stanje = self.tablica[kljuc]
                        self.stog.append(novo_stanje.stanje)
                    else:
                        print("nema unosa u tablici NovoStanje")
                elif (self.akcija.ime_akcije == "Prihvati"):
                    #self.stablo.ispisi()
                    break

                else:
                    print("kriva akcija")
class Stanje:

    def __init__(self, naziv, stanje, lijeva, desna):

        self.ime_akcije = naziv
        self.stanje = stanje
        self.produkcija = [lijeva, desna]

class akcija:
    def __init__(self):
        self.ime_akcije=''
        self.stanje=''
        self.produkcija=[]
        self.lijeva_strana=''
        self.desna_strana=[]

def main():
    sys.stdout = open('izlaz.iz','w')

    file = open('sink.pkl','rb')
    li = pickle.load(file)
    file.close()

    file = open('zav.pkl','rb')
    zavrsni = pickle.load(file)
    file.close()

    file = open('tab.pkl','rb')
    tablica1 = pickle.load(file)
    file.close()
    tablica = {}
    
    for i in tablica1:
        b=Stanje(tablica1[i].ime_akcije,tablica1[i].stanje,tablica1[i].lijeva_strana,tablica1[i].desna_strana)
        tablica.update({i:b})

    #for i in tablica:
        #print(i)
        #print(tablica[i].ime_akcije)
        #print(tablica[i].stanje)
        #if tablica[i].ime_akcije == 'Reduciraj':
            #print(tablica[i].produkcija[0]+'%')
            #print(tablica[i].produkcija[1])

    a = Analizator(li[1])
    file = open('sink.pkl','rb')
    li = pickle.load(file)
    file.close()
    
    for i in li[0]:
        a.sinkronizacijski_znakovi.append(i)

    a.zavrsni_znakovi = zavrsni
    a.sinkronizacijski_znakovi.append("#") #kraj niza mora biti sinkronizacijski znak jer inace oporavak od greske ne radi ako je greska poslije zadnjeg sinkronizacijskog znaka
    a.procitaj_ulaz()
    a.analiziraj(tablica)
    #print("gotovo")
    a.stablo.ispisi()

if __name__ == '__main__':
    main()
